package com.mind.customer.handler.tongwei;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mind.api.ShareAPI;
import com.mind.api.vo.OrderDetailResponse;
import com.mind.api.vo.OrderInfoResponse;
import com.mind.common.constant.CustomerConstants;
import com.mind.common.utils.StringUtils;
import com.mind.common.utils.file.FileUtils;
import com.mind.common.utils.file.vo.FileVo;
import com.mind.customer.api.oss.OSSUtils;
import com.mind.customer.config.FileConfig;
import com.mind.customer.domain.vo.*;
import com.mind.customer.exception.AjObjectNotFoundException;
import com.mind.customer.handler.Handler;
import com.mind.customer.mapper.AjObjectMapper;
import com.mind.customer.mapper.AjReportResultMapper;
import com.mind.system.mapper.AttachResultMapper;
import com.mind.customer.utils.CateUtils;
import com.mind.customer.utils.OrgUtils;
import com.mind.customer.utils.TaskUtils;
import com.mind.system.domain.*;
import com.mind.system.domain.vo.CateResult;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 单据处理器
 */
@Component("tongweiTicketHandler")
@Log4j2
public class TicketHandler implements Handler {


    @Resource
    private ShareAPI shareAPIUtils;

    @Resource
    private OrgUtils orgUtils;

    @Resource
    private AjReportResultMapper reportResultMapper;

    @Resource
    private CheckHandler checkHandler;

    @Resource
    private OCRHandler ocrHandler;

    @Resource
    private BillOrderHandler billOrderHandler;

    @Resource
    private InvoiceHandler invoiceHandler;

    @Resource
    private AttachResultMapper attachResultMapper;

    @Resource
    private FileConfig fileConfig;

    @Resource
    private OSSUtils ossUtils;

    @Resource
    private CateUtils cateUtils;

    @Resource
    private DataSourceHandler dataSourceHandler;

    @Resource
    private AjObjectMapper objectMapper;

    /**
     * 单据处理器
     *
     * @param task
     * @return
     * @throws Exception
     * @throws AjObjectNotFoundException
     */
    public TaskResult handler(AjTicketTask task) throws Exception, AjObjectNotFoundException {
        TaskResult result = new TaskResult() {{
            setStatus(1);
        }};
        // 非标数据
        TaskResult ocrResult = null;
        // 发票数据
        TaskResult invoiceResult = null;
        // 原单数据
        TaskResult billOrderResult = null;

        TaskResult dataSourceResult = null;
        // 检查是否是未上线小类或者特殊小类

        CateResult offsetCateResult = cateUtils.existsCate("未上线", task.getBusinessCate(), task.getTicketType());
        CateResult specialResult = cateUtils.existsCate("混报业务", task.getBusinessCate(), task.getTicketType());
        String ticketId = task.getTicketId();
        try{
            JSONObject jsonObject = JSONObject.parseObject(task.getInfo());
            if(task.getTicketType().equals("DBMYW") &&
                    jsonObject.containsKey("billSourceType") && StringUtils.isNotEmpty(jsonObject.getString("billSourceType")) && jsonObject.getString("billSourceType").contains("商旅")
                    && jsonObject.containsKey("sourceOrderNo") && StringUtils.isNotEmpty(jsonObject.getString("sourceOrderNo"))){
                ticketId = jsonObject.getString("sourceOrderNo");
            }
        }catch (Exception e){
            log.error("单据信息解析错误：{}", task.getInfo(), e);
        }
        if (!TaskUtils.isOnlyCheck(task)) {
            String orgId = getOrgId(task);

            log.info("单据编号：{}, 组织ID：{}", task.getTicketId(), orgId);
            OrderInfoResponse.OrderResult orderInfo = shareAPIUtils.getOrderInfo(orgId, ticketId);
            if (StringUtils.isNull(orderInfo)) {
                orderInfo = new OrderInfoResponse.OrderResult();
            }
            if (orderInfo.getFileList().size()==0) {
                log.error("处理文件列表错误：{}", orderInfo);
            }
            if (orderInfo.getFileList().size()==0) {
                orderInfo.setFileList(new ArrayList<>());
            }
            if (StringUtils.isNotNull(orderInfo.getFileAttributeList())) {
                for (OrderInfoResponse.AttributeList file : orderInfo.getFileAttributeList()) {
                    orderInfo.getFileList().addAll(file.getFileList());
                }
            }
            packageSaveAttachResult(task, orderInfo.getFileList());
            if(!(offsetCateResult.getExists() || specialResult.getExists())){

                try {
                    log.info("OCR数据处理中...");

                    ocrResult = ocrHandler.handler(task, orderInfo.getFileList());
                    if (ocrResult.getStatus() == 2) {
                        return ocrResult;
                    }
                } catch (Exception e) {
                    log.error("OCR处理异常：", e);
                }
            }else{
                List<AjAttachResult> ajAttachResults = attachResultMapper.selectList(new QueryWrapper<AjAttachResult>().eq("ticket_id", task.getTicketId()).eq("version", task.getVersion()));
                for(AjAttachResult ajAttachResult : ajAttachResults){
                    if(ajAttachResult.getStatus().equals("处理中")){
                        ajAttachResult.setStatus("属于混报或业务小类，忽略");
                        attachResultMapper.updateById(ajAttachResult);
                    }
                }
            }
            OrderDetailResponse.OrderDetailResult invoiceDetail = null;
            // 未上线小类 或者混报小类
                try {

                    log.info("发票数据处理中...");
                    Map<String, Map<String, Object>> contentResult = new HashMap<>();
                    for (OrderInfoResponse.FileList file : orderInfo.getFileList()) {
                        if (file.getContentList().size()>0) {
                            for (Map<String, Object> content : file.getContentList()) {
                                Map<String, Object> params = new HashMap<>();
                                params.put("fileUrl", file.getFileUrl());
                                params.put("fileVo", file.getFileVo());
                                params.put("content", content);
                                contentResult.put(content.get("invoiceNumber").toString(), params);
                            }
                        }
                    }
                    invoiceDetail = shareAPIUtils.getOrderDetail(orgUtils.getOrgCode(task.getOrgId()), ticketId, null);
                    invoiceResult = invoiceHandler.handler(task, invoiceDetail, contentResult);
                    if (invoiceResult.getStatus() == 2) {
                        return invoiceResult;
                    }
                } catch (Exception e) {
                    log.error("发票处理异常：", e);
                }
            try {
                log.info("原单数据处理中...");
                billOrderResult = billOrderHandler.handler(task, invoiceDetail);
                if (billOrderResult.getStatus() == 2) {
                    return billOrderResult;
                }
            } catch (Exception e) {
                log.error("原单处理异常：", e);
            }

            try {
//                log.info("数据源处理中...");
//                dataSourceResult = dataSourceHandler.handler(task);
//                if (dataSourceResult.getStatus() == 2) {
//                    return dataSourceResult;
//                }
            } catch (Exception e) {
                log.error("数据源处理异常：", e);
            }
        }
        // 保存
        packageSave(task, ocrResult, invoiceResult, billOrderResult, dataSourceResult);
        //检查
        checkHandler.handle(task);
        return result;
    }

    private String getOrgId(AjTicketTask task) {
        List<AjObject> ajObjectList = objectMapper.selectObjectList(new AjObject() {{
            setTicketType(task.getTicketType());
            setType("OriginalOrder");
        }});
        if (ajObjectList.size()==0) {
            return task.getOrgId();
        }
        AjObject ajObject = ajObjectList.get(0);
        if (ajObject.getName().equals("费报原单")) {
            return JSONObject.parseObject(task.getInfo()).getJSONObject("Basic").getString("eBillOrgCode");
        }
        return task.getOrgId();
    }

    private void packageSaveAttachResult(AjTicketTask task, List<OrderInfoResponse.FileList> fileList) throws
            IOException {
        for (OrderInfoResponse.FileList file : fileList) {
            AjAttachResult result = new AjAttachResult() {{
                setTicketId(task.getTicketId());
                setVersion(task.getVersion());
                setFileName(file.getFileName());
                setFileExtension(file.getFileExtension());
                setFileUrl(file.getFileUrl());
                setTicketType(cateUtils.getTicketTypeByCode(task.getTicketType()));
            }};

            if (!ocrHandler.getOcrSupportFiles().contains(file.getFileExtension())) {
                result.setStatus("忽略");
                packageOffice(file, result);
            } else if (file.getContentList().size()>0) {
                result.setStatus("发票");
                packageOffice(file, result);
            } else {
                // pdf 预览实现
                packageOffice(file, result);
                result.setStatus("处理中");
            }

            attachResultMapper.insert(result);
        }
    }

    /**
     * 打包并保存
     *
     * @param file
     * @param result
     * @throws IOException
     */
    private void packageOffice(OrderInfoResponse.FileList file, AjAttachResult result) throws IOException {
        if (CustomerConstants.OFFICE_LIST.contains( file.getFileExtension())) {
            if (StringUtils.isNotEmpty(file.getFileUrl())) {
                FileVo fileVo = FileUtils.download(file.getFileUrl(), fileConfig.getBasePath(), fileConfig.getBucketName(), null);
                ossUtils.upload(fileVo.getFileName(), fileVo.getFilePath());
                fileVo.setSourceUrl(fileVo.getApiUrl());
                file.setFileVo(fileVo);
                result.setFileUrl(fileVo.getApiUrl());
            }
        }
    }

    /**
     * 打包并保存
     *
     * @param task
     * @param ocrResult
     * @param invoiceResult
     * @param billOrderResult
     */
    private void packageSave(AjTicketTask task, TaskResult ocrResult, TaskResult invoiceResult, TaskResult
            billOrderResult, TaskResult dataSourceResult) {
        Map<String, Object> handlerResult = new HashMap<>();
        Map<String, Object> originalResult = new HashMap<>();
        if (ocrResult != null && ocrResult.getData() != null) {
            handlerResult.putAll(ocrResult.getData());
            originalResult.putAll(ocrResult.getOriginalData());
        }
        if (invoiceResult != null && invoiceResult.getData() != null) {
            handlerResult.putAll(invoiceResult.getData());
            originalResult.putAll(invoiceResult.getOriginalData());
        }
        if (billOrderResult != null && billOrderResult.getData() != null) {
            originalResult.putAll(billOrderResult.getOriginalData());
            handlerResult.putAll(billOrderResult.getData());
        }
        if (dataSourceResult != null && dataSourceResult.getData() != null) {
            handlerResult.putAll(dataSourceResult.getData());
            originalResult.putAll(dataSourceResult.getOriginalData());
        }
        // 如果是只触发规则检查直接拿上一次的
        if (TaskUtils.isOnlyCheck(task)) {
            AjReportResult reportResult = reportResultMapper.selectLastVersionByTicketId(task.getTicketId());
//            if(reportResult )
            handlerResult = JSONObject.parseObject(StringUtils.isEmpty(reportResult.getResult()) ? "{}" : reportResult.getResult());
            originalResult = JSONObject.parseObject(StringUtils.isEmpty(reportResult.getOriginalResult()) ? "{}" : reportResult.getOriginalResult());
        }
        AjReportResult reportResult = reportResultMapper.selectReportResultByTicketId(task.getTicketId(), task.getVersion());
        if (reportResult == null) {
            reportResult = new AjReportResult();
            reportResult.setName(task.getTicketType() + "-" + task.getTicketId());
            reportResult.setReportId(task.getTicketId());
            reportResult.setTicketType(task.getTicketType());
            reportResult.setOrgId(task.getOrgId());
            reportResult.setVersion(task.getVersion());
            reportResult.setResult(JSONObject.toJSONString(handlerResult));
            reportResult.setOriginalResult(JSONObject.toJSONString(originalResult));
            reportResultMapper.insertReportResult(reportResult);
        } else {
            reportResult.setResult(JSONObject.toJSONString(handlerResult));
            reportResult.setOriginalResult(JSONObject.toJSONString(originalResult));
            reportResultMapper.updateReportResult(reportResult);
        }
    }


}
